package com.icinfo.cloud.provider.common.zzd;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient;
import com.alibaba.xxpt.gateway.shared.client.http.GetClient;
import com.alibaba.xxpt.gateway.shared.client.http.PostClient;
import com.icinfo.cloud.provider.common.zzd.dto.AccessTokenInfo;
import com.icinfo.cloud.provider.common.zzd.dto.ZzdUserInfo;
import com.icinfo.framework.common.web.Result;
import com.icinfo.framework.tools.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;


/**
 * 描述：executableClient要单例，并且使用前要初始化，只需要初始化一次.
 *
 * @author ZhangXiaoYan
 * @date 2021-08-02
 */
@Slf4j
@Component
public class ZwddUtil {
    /**
     * 使用volatile关键字防止重排序，因为 new Instance()是一个非原子操作，可能创建一个不完整的实例
     */
    private static volatile ExecutableClient executableClient;
    private static String ACCESS_TOKEN_API = "/gettoken.json";
    private static String USER_INFO_API = "/rpc/oauth2/getuserinfo_bycode.json";
    private static String DINGTALK_APP_USER_API = "/rpc/oauth2/dingtalk_app_user.json";


    ///rpc/oauth2/dingtalk_app_token.json
    /**
     *     中文名：根据员工code获取员工的任职
     *     接口名：/mozi/employee/listEmployeePositionsByEmployeeCode
     *     所在目录：获取通讯录用户信息
     *     调用方式：POST（HTTPS）
     */
    private static String ZZD_POSITIONS_API = "/mozi/employee/listEmployeePositionsByEmployeeCode";
    /**
     * 浙政钉组织查询详情接口
     */
    private static String ZZD_ORG_DETAIL = "/mozi/organization/getOrganizationByCode";

    /**
     * 环境域名
     */
    private static String domainName;

    @Value("${zzd.domainName}")
    private void setDomainName(String domainName) {
        this.domainName = domainName;
    }

    private static String accessKey;

    @Value("${zzd.accessKey}")
    private void setAccessKey(String accessKey) {
        this.accessKey = accessKey;
    }

    private static String appSecret;

    @Value("${zzd.appSecret}")
    private void setAppSecret(String appSecret) {
        this.appSecret = appSecret;
    }

    private ZwddUtil() {

    }

    public static ExecutableClient getClient(String accessKey, String secretKey, String domainName) {
        // Double-Check idiom
        if (executableClient == null) {
            synchronized (ExecutableClient.class) {
                // 只需在第一次创建实例时才同步
                if (executableClient == null) {
                    executableClient = ExecutableClient.getInstance();
                    executableClient.setDomainName(domainName);
                    executableClient.setProtocal("https");
                    executableClient.init();
                }
            }
        }
        executableClient.setAccessKey(accessKey);
        executableClient.setSecretKey(secretKey);
        return executableClient;
    }

    /**
     * 描述：.
     * 返回的json格式：
     * {
     * "success":true,
     * "content":{
     * "data":{
     * "accessToken":"c139fe44362f41b6b84862ec82ab84d9",
     * "expiresIn":"7200"
     * },
     * "requestId":"df04428415724925400701038d663a",
     * "responseMessage":"OK",
     * "responseCode":"0",
     * "success": true
     * }
     * }
     *
     * @return
     * @author zhengqiang
     * @date 2022-12-08
     */
    public static Result<AccessTokenInfo> getAccessTokenNew() {
        ExecutableClient client = ZwddUtil.getClient(accessKey, appSecret, domainName);
        GetClient getClient = client.newGetClient(ACCESS_TOKEN_API);
        getClient.addParameter("appkey", accessKey);
        getClient.addParameter("appsecret", appSecret);
        log.info("获取access_token接口参数=accessKey=" + accessKey+",secretKey="+appSecret);
        String apiResult = getClient.get();
        log.info("获取access_token接口返回结果=" + apiResult);
        if (StringUtils.isBlank(apiResult)) {
            return Result.error("登录失败,政务钉钉接口返回信息为空");
        }
        JSONObject jsonObject = JSONObject.parseObject(apiResult);
        if (true != jsonObject.getBooleanValue("success")) {
            return Result.error("登录失败,错误信息编码：" + jsonObject.getString("errorMsg"));
        }
        AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
        accessTokenInfo.setAccessToken(jsonObject.getJSONObject("content").getJSONObject("data").getString("accessToken"));
        accessTokenInfo.setExpiresIn(jsonObject.getJSONObject("content").getJSONObject("data").getString("expiresIn"));
        return Result.success("获取成功", accessTokenInfo);
    }


    public static String getAccessToken1(String AppKey, String AppSecret){
        PostClient postClient = executableClient.newPostClient(ACCESS_TOKEN_API);
        //设置参数
        postClient.addParameter("appkey", AppKey);
        postClient.addParameter("appsecret", AppSecret);
        //调用API
        String apiResult = postClient.post();
        JSONObject jsonObject = JSONObject.parseObject(apiResult);
        String accessToken = (String)jsonObject.getJSONObject("content").getJSONObject("data").get("accessToken");
        Integer expiresIn = (Integer)jsonObject.getJSONObject("content").getJSONObject("data").get("expiresIn");
        //TODO 优化放入redis
        //redisManager.set (Constants.DINGDING_ACCESS_TOKEN, accessToken, expiresIn);
        //  log.info("----------------------------"+accessToken);
        return accessToken;
    }

    //获取浙政钉用户信息
    public static Result<ZzdUserInfo> getZWDingdingUser(String accessToken, String authCode) {
        log.info("获取用户请求参数: accessToken=" + accessToken + ";authCode=" + authCode);
        if (executableClient == null) {
            executableClient = ZwddUtil.getClient(accessKey, appSecret, domainName);
        }
        PostClient postClient = executableClient.newPostClient(DINGTALK_APP_USER_API);
        //设置参数
        postClient.addParameter("access_token", accessToken);
        postClient.addParameter("auth_code", authCode);
        String result = postClient.post();
        log.info("getZWDingdingUser result ......" + result);
        if (ObjectUtils.isEmpty(result)) {
            return Result.error("登录失败,政务钉钉接口返回用户信息为空");
        }
        JSONObject userInfoJson = JSONObject.parseObject(result);
        if (true != userInfoJson.getBooleanValue("success") ) {
            return Result.error("登录失败,未获取到内容");
        }
        if (true != userInfoJson.getJSONObject("content").getBoolean("success")){
            String msg = userInfoJson.getJSONObject("content").getString("responseMessage");
            return Result.error(msg);
        }
        String userInfoJsonStr = userInfoJson.getJSONObject("content").getJSONObject("data").toJSONString();
        ZzdUserInfo zzdUserInfo = JSONObject.parseObject(userInfoJsonStr, ZzdUserInfo.class);
        return Result.success("信息获取成功", zzdUserInfo);
    }

    public  String getJsapiToken1(String AppKey, String AppSecret){

        String api = "/get_jsapi_token.json";
        PostClient postClient = executableClient.newPostClient(api);
        //设置参数
        postClient.addParameter("accessToken", getAccessToken1(AppKey, AppSecret));
        /*postClient.addParameter("receiverIds", "73800820");*/
        //调用API
        String result = postClient.post();
        JSONObject jsonObject = JSONObject.parseObject(result);
        String accessToken = (String)jsonObject.getJSONObject("content").getJSONObject("data").get("accessToken");
        Integer expiresIn = (Integer)jsonObject.getJSONObject("content").getJSONObject("data").get("expiresIn");
        log.info("JsapiToken {}", jsonObject.toJSONString());
        //TODO
        //redisManager.set (Constants.DINGDING_JSAPI_TOKEN, accessToken, expiresIn);
        return accessToken;
    }

    /**
     * 描述：获取授权用户的个人信息.
     * 成功的格式：
     * {
     *     "success": true,
     *     "content": {
     *         "data": {
     *             "lastName": "张小燕",
     *             "realmId": 1929,
     *             "clientId": "jhzhjg_dingoa",
     *             "realmName": "浙政钉租户",
     *             "nickNameCn": "张小燕",
     *             "tenantUserId": "1969$643675",
     *             "avatar": "$iwHRKaUKAAvSQf7v7749N3YfFa-G4vel8xNzYwOTE2MTlhNgfSA9mfCwgACaJpbQ",
     *             "employeeCode": "GE_541e30576e985e75f",
     *             "accountId": 645675,
     *             "tenantName": "浙政钉租户",
     *             "namespace": "local",
     *             "tenantId": 1969,
     *             "account": "df2128@@500"
     *         },
     *         "success": true,
     *         "responseMessage": "成功",
     *         "responseCode": "0"
     *     }
     * }
     * 无效的格式：
     * {
     *     "success": true,
     *     "content": {
     *         "success": false,
     *         "responseMessage": "code失效或不存在",
     *         "responseCode": "240111",
     *         "bizErrorCode": "MBS-B001-02-16-240111"
     *     }
     * }
     * @param accessToken
     * @param code
     * @return
     * @author ZhangXiaoYan
     * @date 2021-08-05
     */
    public static Result<ZzdUserInfo> getUserInfoByQrCode(String accessToken, String code) {
        ExecutableClient client = ZwddUtil.getClient(accessKey, appSecret, domainName);
        PostClient userInfoClient = client.newPostClient(USER_INFO_API);
        //设置参数
        userInfoClient.addParameter("appkey", accessKey);
        userInfoClient.addParameter("appsecret", appSecret);
        userInfoClient.addParameter("code", code);
        userInfoClient.addParameter("access_token", accessToken);
        //调用API
        log.info("获取getuserinfo_bycode接口参数=" + JSON.toJSONString(userInfoClient.parameterList()));
        String userinfoResult = userInfoClient.post();
        log.info("获取getuserinfo_bycode接口返回结果=" + userinfoResult);
        if (StringUtils.isBlank(userinfoResult)) {
            return Result.error("扫码登录失败,政务钉钉接口返回用户信息为空");
        }
        JSONObject userInfoJson = JSONObject.parseObject(userinfoResult);
        if (true != userInfoJson.getBooleanValue("success") ) {
            return Result.error("扫码登录失败,未获取到内容");
        }
        if (true != userInfoJson.getJSONObject("content").getBoolean("success")){
            String msg = userInfoJson.getJSONObject("content").getString("responseMessage");
            return Result.error(msg);
        }
        String userInfoJsonStr = userInfoJson.getJSONObject("content").getJSONObject("data").toJSONString();
        ZzdUserInfo zzdUserInfo = JSONObject.parseObject(userInfoJsonStr, ZzdUserInfo.class);
        return Result.success("信息获取成功", zzdUserInfo);
    }

    /**
     * 通过手机号码获取政务钉id
     *
     * @param
     * @return
     * @author wangqinghai
     * @date 2021/5/6
     */
    /*public static Result<List<ZzdUserInfo>>  getAccountIdByMobiles(String accessKey, String secretKey, String domainName, List<String> mobileList,Long tenantId) throws Exception {
        if (ObjectUtils.isEmpty(mobileList)){
            return Result.success(Lists.newArrayList());
        }
        ExecutableClient client = ZwddUtil.getClient(accessKey, secretKey, domainName);
        GetClient postClient = client.newGetClient("/mozi/employee/get_by_mobiles");

        //设置参数
        postClient.addParameter("areaCode", "86");
        postClient.addParameter("tenantId", String.valueOf(tenantId));
        postClient.addParameter("namespace", "local");
        postClient.addParameter("mobiles", String.join(",",mobileList));
        //调用API
        String apiResult = postClient.get();
        System.out.println(apiResult);

        if (StringUtils.isBlank(apiResult)) {
            throw new Exception("接口：" + "" +"调用失败");
        }
        //调用API

        log.info("获取postClient接口返回结果=" + apiResult);

        JSONObject userInfoJson = JSONObject.parseObject(apiResult);
        if (true != userInfoJson.getBooleanValue("success") ) {
            return Result.error("未获取到内容"+userInfoJson.getString("errorMsg"));
        }
        if (true != userInfoJson.getJSONObject("content").getBoolean("success")){
            String msg = userInfoJson.getJSONObject("content").getString("responseMessage");
            return Result.error(msg);
        }
        String data= userInfoJson.getJSONObject("content").getJSONArray("data").toString();

        List<ZzdUserInfo> zzdOrgEmployeeList = JSONArray.parseArray(data, ZzdUserInfo.class);

        return Result.success("信息获取成功", zzdOrgEmployeeList);
    }*/

    /*public static Result<List<ZzdPositions>> getPositionsByEmployeeCode(String accessKey, String secretKey, String domainName, String employeeCode ,Long tenantId) {
        if (ObjectUtils.isEmpty(employeeCode)){
            return Result.success(Lists.newArrayList());
        }
        ExecutableClient client = ZwddUtil.getClient(accessKey, secretKey, domainName);
        PostClient userInfoClient = client.newPostClient(ZZD_POSITIONS_API);
        if (ObjectUtils.isEmpty(employeeCode)){
            return Result.error("employeeCode为空");
        }
        userInfoClient.addParameter("appkey", accessKey);
        userInfoClient.addParameter("appsecret", secretKey);
        userInfoClient.addParameter("employeePositionStatus","TOTAL");
        userInfoClient.addParameter("employeePositionType","EMPLOYEE_POSITION_ALL");
        userInfoClient.addParameter("employeeCode",employeeCode);
        userInfoClient.addParameter("tenantId", String.valueOf(tenantId));

        //调用API
        log.info("获取getPositionsByEmployeeCode接口参数=" + JSON.toJSONString(userInfoClient.parameterList()));
        String userinfoResult = userInfoClient.post();
        log.info("获取getPositionsByEmployeeCode接口返回结果=" + userinfoResult);

        JSONObject userInfoJson = JSONObject.parseObject(userinfoResult);
        if (true != userInfoJson.getBooleanValue("success") ) {
            return Result.error("未获取到内容"+userInfoJson.getString("errorMsg"));
        }
        if (true != userInfoJson.getJSONObject("content").getBoolean("success")){
            String msg = userInfoJson.getJSONObject("content").getString("responseMessage");
            return Result.error(msg);
        }
        String data= userInfoJson.getJSONObject("content").getJSONArray("data").toString();
        List<ZzdPositions> zzdOrgEmployeeList = JSONArray.parseArray(data, ZzdPositions.class);
        return Result.success("信息获取成功", zzdOrgEmployeeList);
    }*/

    /**
     * 描述：获取组织机构详情
     *
     * @param accessKey
     * @param secretKey
     * @param domainName
     * @param zzdOrgRequest
     *
     */
    /*public static Result<ZzdOrgDTO> getZzdOrgDetail(String accessKey, String secretKey, String domainName, String orgCode, String tenantId) {
        ExecutableClient client = ZwddUtil.getClient(accessKey, secretKey, domainName);
        PostClient orgClient = client.newPostClient(ZZD_ORG_DETAIL);
        //设置参数
        orgClient.addParameter("tenantId", tenantId);
        orgClient.addParameter("organizationCode", orgCode);

        //调用API
        String orgUserResult = orgClient.post();
        log.debug("查询组织机构详情返回结果:" + orgUserResult);
        if (StringUtils.isBlank(orgUserResult)) {
            return Result.error("查询组织机构详情返回结果为空");
        }
        JSONObject orgJson = JSONObject.parseObject(orgUserResult);
        if (true != orgJson.getBooleanValue("success") ) {
            return Result.error("查询组织机构详情返回结果,未获取到内容");
        }
        if (true != orgJson.getJSONObject("content").getBoolean("success")){
            String msg = orgJson.getJSONObject("content").getString("responseMessage");
            return Result.error(msg);
        }
        String orgJsonStr = orgJson.getJSONObject("content").get("data").toString();
        //转化json对象
        ZzdOrgDTO zzdOrgDTO = JSONObject.parseObject(orgJsonStr, ZzdOrgDTO.class);
        return Result.success("信息获取成功", zzdOrgDTO);
    }*/

}

